package taskenum

import (
	"yunj/pkg/yunj/core/enum"
)

// 此处不自定义类型，防止数据库占位符?替换为字符串，在mysql进行匹配时发生类型转换

// 定义常量
const (
	// 等待中
	STATUS_PENDING uint8 = 11

	// 处理中
	STATUS_PROCESSING uint8 = 22

	// 已完成
	STATUS_COMPLETED uint8 = 33

	// 失败
	STATUS_FAILED uint8 = 44

	// 已取消
	STATUS_CANCELLED uint8 = 55
)

// 实现EnumInerface接口
type Status struct {
	enum.Enum[uint8]
}

// Status.GetInstance().GetDescMap()
func (e *Status) AllConstAttrs() map[uint8]map[string]any {
	return map[uint8]map[string]any{
		STATUS_PENDING: {
			"desc":            "等待中",
			"sort":            1,
			"color":           "#2F363C",
			"allowLastStatus": []any{STATUS_PROCESSING, STATUS_CANCELLED}, // 允许上一个状态，兼容失败和已取消任务重新执行
		},
		STATUS_PROCESSING: {
			"desc":            "处理中",
			"sort":            2,
			"color":           "#31BDEC",
			"allowLastStatus": []any{STATUS_PENDING, STATUS_PROCESSING},
		},
		STATUS_COMPLETED: {
			"desc":            "已完成",
			"sort":            3,
			"color":           "#009688",
			"allowLastStatus": []any{STATUS_PROCESSING},
		},
		STATUS_FAILED: {
			"desc":            "失败",
			"sort":            4,
			"color":           "#FF5722",
			"allowLastStatus": []any{STATUS_PROCESSING},
		},
		STATUS_CANCELLED: {
			"desc":            "已取消",
			"sort":            5,
			"color":           "#2F363C",
			"allowLastStatus": []any{STATUS_PENDING, STATUS_PROCESSING},
		},
	}
}

// 获取允许的上一个状态
func (e *Status) GetAllowLastStatus() (res []any) {
	allowLastStatusRaw := e.GetAttr("allowLastStatus")
	if allowLastStatusRaw == nil {
		return
	}
	if allowLastStatus, ok := allowLastStatusRaw.([]any); ok {
		res = allowLastStatus
	}
	return
}

// 存储已经创建的实例
var statusInstanceCache = make(map[uint8]*Status)

// 根据value获取枚举
func StatusByValue(value uint8) *Status {
	if instance, exists := statusInstanceCache[value]; exists {
		return instance
	}
	e := &Status{}
	enum.SetEnumInstance(&e.Enum, e, value)
	statusInstanceCache[value] = e
	return e
}

var StatusEnum *Status = func() *Status {
	e := &Status{}
	enum.SetEnumInstance(&e.Enum, e)
	return e
}()
